//
// Created by Suzhen on 2017/2/24.
//

#ifndef ORIONV2_FILEASYNCSTREAM_H
#define ORIONV2_FILEASYNCSTREAM_H

#include "AbstractAsyncStream.h"
#include "IOBuffer.h"

ORION_V2_NAMESPACE_BEGIN

        /**
         * 文件数据流
         */
        class FileStream : public AbstractAsyncStream {

        public :

            virtual ~FileStream();

            /**
             * FileStream
             * @param fd 文件描述符,0表示不设置,但是在 attach 时,会断言失败
             * @param ioBehavior IO行为描述
             * @param readTimeOut 0 表示永不超时
             */
            explicit FileStream(FdType fd,
                                const IOBehavior &ioBehavior,
                                uint readTimeOut);

        public:

            void attach(AsyncEventGenerator *gen) override;

            bool isClosed() override;

            bool isClosing() override;

            Future<bool> sendAsync(IOBuffer &&buffer) override;

            Future<bool> sendAsync(const RawDataType *buf,
                                   size_t bufSz,
                                   bool transferData);

            Future<bool> closeAsync() override;

            virtual void activate(EventFlag e) override;

            //File 默认 IO 回调
            static void DefaultIOCallBack(PollContext *handle, int status, EventFlag events);

        protected:
            /**
             * 重置 timer 重设计时器
             */
            void resetTimer();

            /**
             * 文件描述符 打开事件通知
             */
            void OnOpen();

            /**
             * 文件描述符 关闭事件通知
             */
            void OnClosed();

            /**
             * 文件描述符 有数据可读
             */
            void OnDataRead(const RawDataType *, size_t);


        private:

            //底层组件 异步关闭的回调
            static void UninstallHandlesCallBack(uv_handle_t *h);

            //异步关闭请求的回调
            static void AsyncCloseCallBack(uv_async_t *async);

            //异步发送数据的回调
            static void AsyncSendCallBack(uv_async_t *async);

            //空闲回调
            static void IdleTimerCallBack(uv_timer_t *timer);

        protected:
            //底层异步对象
            AsyncPollData coreAsyncPollData{};
            //
            std::list<IOBuffer> dataWillSend_{};
            //绑定在底层系统引用计数
            int openInHandle_{0};
            //
            AsyncContext sendAsyncCtx_;
            AsyncContext closeAsyncCtx_;
            TimerContext idleTimerCtx_;
            //IO超时时间
            uint idleTimeMs_{DEFAULT_STREAM_IDLE_MS};
            //todo isClosing_ 和 isClosed_ 改用状态机来实现
            bool isClosing_{NO};
            bool isClosed_{NO};
            std::recursive_mutex dataLock_{};
            Promise<bool> closePromise_{};
        };

ORION_V2_NAMESPACE_END


#endif //ORIONV2_FILEASYNCSTREAM_H
